package junit;

import java.lang.reflect.Method;
import java.util.Set;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.JoinColumn;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.EntityType;

import org.junit.BeforeClass;
import org.junit.Test;
import org.maiyoframework.assist.entity.UserRes;
import org.maiyoframework.core.common.BeanUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

@SuppressWarnings({ "rawtypes", "unchecked" })
public class JpaMetamodelTest {

	private static EntityManager em;

	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		try {
			ApplicationContext ac = new ClassPathXmlApplicationContext("junit/spring-junit.xml");
			EntityManagerFactory emf = (EntityManagerFactory) ac.getBean("entityManagerFactory");
			em = emf.createEntityManager();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Test
	public void metamodel() throws SecurityException, NoSuchMethodException {
		EntityType<UserRes> classMetamodel = em.getMetamodel().entity(UserRes.class);
		// 实体名称
		System.out.println(classMetamodel.getName());
		// 主键
		Class idTypeClass = classMetamodel.getIdType().getJavaType();
		System.out.println(classMetamodel.getId(idTypeClass).getName());
		System.out.println("--------------------------");
		// 获取所有属性
		Set<Attribute<? super UserRes, ?>> attributes = classMetamodel.getAttributes();
		for (Attribute attribute : attributes) {
			if(attribute.getPersistentAttributeType().name().equals("MANY_TO_ONE")){
				Method method = UserRes.class.getMethod(BeanUtils.catchGetMethodByProperty(attribute.getName()));
				JoinColumn jc = method.getAnnotation(JoinColumn.class);
				System.out.println(jc.name());
			}
			System.out.println(attribute.getName() + " : "
					+ attribute.getPersistentAttributeType() + " : "
					+ attribute.getPersistentAttributeType().name() + " : "
					+ attribute.getPersistentAttributeType().ordinal());
		}
		System.out.println("--------------------------");
		// 获取单值属性
//		Set<SingularAttribute<? super User, ?>> singularAttributes = classMetamodel.getSingularAttributes();
//		for(SingularAttribute singularAttribute : singularAttributes){
//			System.out.println(singularAttribute.getName());
//		}
		System.out.println("--------------------------");
		// 获取muti-value，包括set，list，map等
//		Set<PluralAttribute<? super User, ?, ?>> pluralAttributes = classMetamodel.getPluralAttributes();
//		for(PluralAttribute pluralAttribute : pluralAttributes){
//			System.out.println(pluralAttribute.getName());
//		}
		// 更多方法
//		for(Attribute s: attributes){
//			System.out.println("getName >> "+s.getName());
//			System.out.println("getBindableJavaType >> "+s.getBindableJavaType());
//			System.out.println("getBindableType >> "+s.getBindableType());
//			System.out.println("getDeclaringType >> "+s.getDeclaringType());
//			System.out.println("getJavaMember.getName >> "+s.getJavaMember().getName());
//			System.out.println("getJavaMember.getModifiers >> "+s.getJavaMember().getModifiers());
//			System.out.println("getJavaType >> "+s.getJavaType());
//			System.out.println("getPersistentAttributeType >> "+s.getPersistentAttributeType());
//			System.out.println("getType >> "+s.getType());
//		}
	}

}
